#include "manano_common.h"

#include "mdtx-online/indicator/indicator_type_s4_skewness.h"
namespace indi = mdtx::online::indicator;

using rollskew_np = unary3<indi::rollskew_np>;
using rollskew_npw = binary3<indi::rollskew_npw>;

using rollskew_mc = unary3<indi::rollskew_mc>;
using rollskew_quantile = unary3<indi::rollskew_quantile>;
using rollskew_G1 = unary3<indi::rollskew_G1>;
using rollskew_G1cu = unary3<indi::rollskew_G1cu>;

void bind_indi_s4_skewness(py::module &m)
{
    auto mod = m.def_submodule("skewness", "Rolling skewness");
    {
        auto v = py::class_<rollskew_np>(mod, "nonpara")
                     .def(py::init<int>(), py::arg("period"))
                     .def("run", &rollskew_np::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           median (float64)
                           SD (fload64)
                           skewness (float64))mydoc")
                     .def("run", &rollskew_np::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           median (numpy.array)
                           SD (numpy.array)
                           skewness (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Rolling skewness, non parametric defined by sk = (m - med) / SD
                    Args:
                        period (int) : rolling window period)mydoc";
    }
    {
        auto v = py::class_<rollskew_npw>(mod, "nonpara_w")
                     .def(py::init<int>(), py::arg("period"))
                     .def("run", &rollskew_npw::run, py::arg("x"), py::arg("w"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                           w (float64) : weight
                        Return:
                           median (float64)
                           SD (fload64)
                           skewness (float64))mydoc")
                     .def("run", &rollskew_npw::run2, py::arg("x"), py::arg("w"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                           w (numpy.array) : weights
                        Return:
                           median (numpy.array)
                           SD (numpy.array)
                           skewness (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Rolling skewness, weighted non parametric defined by sk = (m - med) / SD
                    Args:
                        period (int) : rolling window period)mydoc";
    }
    {
        auto v = py::class_<rollskew_mc>(mod, "medcouple")
                     .def(py::init<int>(), py::arg("period"))
                     .def("run", &rollskew_mc::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           median (float64)
                           IQR (fload64)
                           skewness (float64))mydoc")
                     .def("run", &rollskew_mc::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           median (numpy.array)
                           IQR (numpy.array)
                           skewness (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Rolling skewness, medcouple algorithm
                    Args:
                        period (int) : rolling window period)mydoc";
    }
    {
        auto v = py::class_<rollskew_quantile>(mod, "quantile")
                     .def(py::init<int>(), py::arg("period"))
                     .def("run", &rollskew_quantile::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           median (float64)
                           IQR (fload64)
                           skewness (float64))mydoc")
                     .def("run", &rollskew_quantile::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           median (numpy.array)
                           IQR (numpy.array)
                           skewness (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Rolling skewness, quantile based, defined by sk = ((Q3 - med) + (Q1 - med)) / (Q3 - Q1)
                    Args:
                        period (int) : rolling window period)mydoc";
    }
    {
        auto v = py::class_<rollskew_G1>(mod, "G1")
                     .def(py::init<int>(), py::arg("period"))
                     .def("run", &rollskew_G1::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           mean (float64)
                           SD (fload64)
                           skewness (float64))mydoc")
                     .def("run", &rollskew_G1::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           mean (numpy.array)
                           SD (numpy.array)
                           skewness (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Rolling skewness, G1 coefficient
                    Args:
                        period (int) : rolling window period)mydoc";
    }
    {
        auto v = py::class_<rollskew_G1cu>(mod, "G1cu")
                     .def(py::init())
                     .def("run", &rollskew_G1cu::run, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (float64) : input data
                        Return:
                           mean (float64)
                           SD (fload64)
                           skewness (float64))mydoc")
                     .def("run", &rollskew_G1cu::run2, py::arg("x"),
                     R"mydoc(
                        Run calculation
                        Args:
                           x (numpy.array) : input data
                        Return:
                           mean (numpy.array)
                           SD (numpy.array)
                           skewness (numpy.array))mydoc");
        v.doc() = R"mydoc(
                    Cumulative skewness, G1 coefficient
                    Args:
                        period (int) : rolling window period)mydoc";
    }
}
